////////////////////////////////////////////////////////////////////////////////
// REGULAR EXPRESSION STRINGS/GENERIC FUNCTIONS FOR PATTERN MATCHING.         //
// Since '\' character also denotes special character in a Javascript string, //
// '\\' required to express '\' for a regular expression stored in a string.  //
////////////////////////////////////////////////////////////////////////////////

// --- NUMBERS --- //

var re_number = /^\d+$/;

// An infinite length integer
var re_integer = "(\\+|\\-)?(\\d+)";

// An infinite length positive integer
var re_pos_integer = "\\+?(\\d+)";

// An infinite length negative integer
var re_neg_integer = "\\-?(\\d+)";

// Any number of zeroes
var re_zero = "(\\+|\\-)0+";


// --- STRINGS --- //

// All whitespace
var re_all_whitespace = "^\\s*$";

// Starting/ending whitespace
var re_start_end_whitespace = "^\\s*|\\s*$";

// Host/domain name with/without leading periods (.trendmicro.com, 
// trendmicro.com, ...)
var re_postfix_domain = "(\\.{0,1}[a-zA-Z0-9\\-]+)+";

// Host/domain name (trendmicro.com, trendmicro, ...)
var re_valid_domain_chars = "[a-zA-Z0-9\\-.]";

// Invalid usage of '.' in domain-style string (.abc, abc., a..b, etc).
// This is sufficient for checking the pattern of an IP address/domain name
var re_invalid_domain_period_usage = "(^\\.)|(\\.$)|(\\.\\.)";

// E-mail address pattern
var re_email_address_pattern = "(.+)@(.+)";

// Valid e-mail address characters (user) \[^\\w<>\\.!#$%&'*+-\\/=\\?^`{\\|}~\"\\(\\)\]
// TODO: Is "*" valid here? var re_valid_email_address_chars_user = "[\\w<>.!#$%&'*+\\-/=?^`{|}~\"()]";
var re_valid_email_address_chars_user = "[\\w<>.!#$%&'+\\-/=?^`{|}~\"()]";

// Valid e-mail address characters (domain)
var re_valid_email_address_chars_domain = "[\\w.!#$%&'*+\\-/=?^`{|}~\"]";

// Only matches a string with all non-DBCS characters (ASCII value <= 127)
var re_non_dbcs_chars = "[\\x00-\\xEF]*";

var re_windows_path_pattern = /^[a-zA-Z]:[\\\/](.*)$/;

// Invalid file path characters
var re_invalid_path_chars = /[:"*?<>|]/g;

// Invalid file path patterns
var re_invalid_path_patterns = /(\\{2})|(\/{2})|(\.{2})/g;

// Contains a " character
var re_contains_double_quote = /["]/g;




////////////////////////////////////////////////////////////////////////////////
// PROTOTYPES                                                                 //
// Extend the functionality of existing objects.                              //
////////////////////////////////////////////////////////////////////////////////

//
// String object
//
String.prototype.removeWhitespace = _removeWhitespace;
String.prototype.removeAllWhitespace = _removeAllWhitespace;
String.prototype.isWhitespace = _isWhitespace;

// [DESC] Removes whitespace from beginning/end of string
// [IN]   None
// [OUT]  String: start/end whitespace removed
function _removeWhitespace()
{
    return this.replace(new RegExp(re_start_end_whitespace,"g"),"");
}

// [DESC] Removes all whitespace
// [IN]   None
// [OUT]  String: all whitespace removed
function _removeAllWhitespace()
{
    return this.replace(new RegExp("\\s","g"),"");
}

// [DESC] Returns true if string is all whitespace
// [IN]   str[String]: String
// [OUT]  True if string is all whitespace, else false
function _isWhitespace()
{
    return (new RegExp(re_all_whitespace)).test(this);
}


////////////////////////////////////////////////////////////////////////////////
// FORMAT CHECKING FUNCTIONS                                                  //
// These functions check the format of the input string and return true       //
// for a correct match.                                                       //
////////////////////////////////////////////////////////////////////////////////

// [DESC] Checks the format of an absolute pathname
// [IN]   str [String]: Integer
// [OUT]  Boolean
function checkAbsolutePath_Format(str)
{    
    return !(re_invalid_path_chars.test(str) || re_invalid_path_patterns.test(str));
}

// [DESC] Checks the format of an integer
// [IN]   str [String]: Integer
// [OUT]  Boolean
function checkInteger_Format(str)
{
    return (new RegExp("^" + re_integer + "$")).test(str);
}

// [DESC] Checks the format of an IPv4 IP address 
// [IN]   str [String]: IPv4 IP address
// [OUT]  Boolean
function checkIPv4_Format(str)
{
    re = new RegExp("^" + re_ipv4_pattern + "$","gi");
    ipArray = re.exec(str);
    if (!ipArray)
        return false;

    for (var i = 1; i <= 4; i++)
        if (ipArray[i] < 0 || ipArray[i] > 255)
            return false;

    return true;
}

// [DESC] Checks the format of a Postfix transport map domain entry
// [IN]   str [String]: Postfix host/domain name
// [OUT]  Boolean
function checkPostfixDomain_Format(str)
{
    re = new RegExp("^" + re_postfix_domain + "$");
    return re.test(str);
}

// [DESC] Checks the format of a standard domain name
// [IN]   str [String]: host/domain name
// [OUT]  Boolean
function checkDomain_Format(str)
{
    re_chars = new RegExp("^" + re_valid_domain_chars + "+$");
    re_pattern = new RegExp(re_invalid_domain_period_usage,"g");
    return (re_chars.test(str) && !re_pattern.test(str));
}

// [DESC] Checks the format of a wildcard domain name
// [IN]   str [String]: host/domain name
// [OUT]  Boolean
function checkWildcardDomain_Format(str)
{
    allDomains = (str == "*");
    subDomains = (str.substr(0,2) == "*." && checkDomain_Format(str.substr(2)));    
    singleDomain = checkDomain_Format(str);
    return (allDomains || subDomains || singleDomain);
}

// [DESC] Checks the format of a standard user@domain e-mail address
// [IN]   str [String]: e-mail address 
// [OUT]  Boolean
function checkEmailAddress_Format(str)
{
    var re = new RegExp("^" + re_email_address_pattern + "$");
    matched_substrings = str.match(re);
    if (!matched_substrings)
        return false;

    var re_user_chars = new RegExp("^" + re_valid_email_address_chars_user + "+$");
    var re_domain_chars = new RegExp("^" + re_valid_email_address_chars_domain + "+$");
    var re_invalid_period_usage = new RegExp(re_invalid_domain_period_usage,"g");

    var userValid = re_user_chars.test(matched_substrings[1]) && 
                    !re_invalid_period_usage.test(matched_substrings[1]);
    var domainValid = re_domain_chars.test(matched_substrings[2]) &&
                      !re_invalid_period_usage.test(matched_substrings[2]);

    return (userValid && domainValid);
}

// [DESC] Checks the format of a wildcard user@domain e-mail address
//        Valid formats: *@*, *@domain.com, user@*.com, *@*.com, user@domain.com
// [IN]   str [String]: e-mail address 
// [OUT]  Boolean
function checkWildcardEmailAddress_Format(str)
{
    var re_pattern = new RegExp("^" + re_email_address_pattern + "$");
    var matched_substrings = re_pattern.exec(str);
    if (!matched_substrings)
        return false;

    var re_user_chars = new RegExp("^" + re_valid_email_address_chars_user + "+$");
    var re_domain_chars = new RegExp("^" + re_valid_email_address_chars_domain + "+$");

    var userValid = (matched_substrings[1] == "*" || re_user_chars.test(matched_substrings[1]));
    var domainValid = checkWildcardDomain_Format(matched_substrings[2]);

    return (userValid && domainValid);
                 
}

// [DESC] Checks the format of multiple e-mail addresses
// [IN]   str [String]: e-mail address(es)
// [OUT]  Boolean
function checkEmailAddressMultiple_Format(str)
{
    re_bad_delimiters = /(;,)|(,;)|(,{2})|(;{2})/g;
	if (re_bad_delimiters.test(str))
	    return false;

    splitString = str.split(new RegExp("[;,]"));
    if (splitString.length == 0)
        return false;

    for (var i = 0; i < splitString.length; i++)
    {
        if (!checkEmailAddress_Format(splitString[i]))
            return false;
    }
    return true;
}

// [DESC] Checks string for ASCII-only characters
// [IN]   str [String]: string of ASCII characters
// [OUT]  Boolean
function checkASCII_Format(str)
{
    if (str.isWhitespace())
        return false;
    return (new RegExp("^" + re_non_dbcs_chars + "$")).test(str);
}

////////////////////////////////////////////////////////////////////////////////
// INPUT MANIPULATION FUNCTIONS                                               //
// Functions for manipulating input.                                          //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

// [DESC] Removes leading zeros from str
// [IN]   str [String]: Number string
// [OUT]  If NaN, return NaN.  Else, return Number.
function trimLeadingZeroes(str)
{
    if (str.isWhitespace())
        return Number.NaN;
    return new Number(str);
}

// [DESC] Clamps the number value stored in field pointed to by obj
//        min <= obj.value <= max
// [IN]   obj [Object]: Form Text input field
//        min [Number]: Minimum value
//        max [Number]: Maximum value
// [OUT]  Boolean: If successful, return true, else return false.
function clampNumberValue(obj, min, max)
{
    if (!obj.value || isNaN(min) || isNaN(max) || min > max)
        return false;
    
    if (obj.value < min)
        obj.value = min;
    else if (obj.value > max)
        obj.value = max;

    return true;
}

// please put onblur="checkdate(this)" in fromDate and toDate textbox and
// put onclick="return doDateCheck(this.form.fromDate, this.form.toDate, this.form.fromHH, this.form.fromMM, this.form.toHH, this.form.toMM)"
// in submit button and the dates will be vaildated.
function checkdate(objName) {
var datefield = objName;
if (chkdate(objName) == false) {
datefield.select();
//alert("That date is invalid.  Please try again.");
datefield.focus();
return false;
}
else {
return true;
   }
}

function chkdate(objName) {
var strDatestyle = "US"; //United States date style
var strDate;
var strDateArray;
var strDay;
var StrDay1;
var strMonth;
var strMonth1;
var strYear;
var strYear1;
var strYear2;
var strYear3;
var intday;
var intday1;
var intMonth;
var intMonth1;
var intYear;
var intYear1;
var intYear2;
var intYear3;
var booFound = false;
var datefield = objName;
var strSeparatorArray = new Array("/");
var intElementNr;
var err = 0;
var strMonthArray = new Array(12);
strMonthArray[0] = "Jan";
strMonthArray[1] = "Feb";
strMonthArray[2] = "Mar";
strMonthArray[3] = "Apr";
strMonthArray[4] = "May";
strMonthArray[5] = "Jun";
strMonthArray[6] = "Jul";
strMonthArray[7] = "Aug";
strMonthArray[8] = "Sep";
strMonthArray[9] = "Oct";
strMonthArray[10] = "Nov";
strMonthArray[11] = "Dec";
strDate = datefield.value;
if (strDate.length < 1) {
return true;
}
for (intElementNr = 0; intElementNr < strSeparatorArray.length ; intElementNr++) {
if ( strDate.indexOf( strSeparatorArray[intElementNr] ) != -1 ) {
strDateArray = strDate.split(strSeparatorArray[intElementNr]);
if (strDateArray.length < 3) {
err = 1;
return false;
}
else {
strDay = strDateArray[0];
strMonth = strDateArray[1];
strYear = strDateArray[2];
}
booFound = true;
   }
}
if (booFound == false) {
  return false;
}

if (strDay.length == 1) {
strDay = '0' + strDay;
}

if (strMonth.length == 1) {
strMonth = '0' + strMonth;
}

if (strYear.length == 1) {
strYear = '000' + strYear;
}
if (strYear.length == 2) {
strYear = '00' + strYear;
}
if (strYear.length == 3) {
strYear = '0' + strYear;
}
if (strYear.length != 4) {
return false;
}
// US style
if (strDatestyle == "US") {
strTemp = strDay;
strDay = strMonth;
strMonth = strTemp;
}
if (strDay.length != 2) {
return false;
}

if (strMonth.length != 2) {
return false;
}

strDay1 =  strDay.substring(1,2); 
strMonth1 =  strMonth.substring(1,2);
strYear1=strYear.substring(1,2);
strYear2=strYear.substring(2,3);
strYear3=strYear.substring(3,4);


intday = parseInt(strDay, 10);
intday1= parseInt(strDay1, 10);
if (isNaN(intday)|| isNaN(intday1)) {
err = 2;
return false;
}
intMonth = parseInt(strMonth, 10);
intMonth1 = parseInt(strMonth1, 10);
if (isNaN(intMonth)) {
for (i = 0;i<12;i++) {
if (strMonth.toUpperCase() == strMonthArray[i].toUpperCase()) {
intMonth = i+1;
strMonth = strMonthArray[i];
i = 12;
   }
}
if (isNaN(intMonth)|| isNaN(intMonth1)) {
err = 3;
return false;
   }
}
intYear = parseInt(strYear, 10);
intYear1 = parseInt(strYear1, 10);
intYear2 = parseInt(strYear2, 10);
intYear3 = parseInt(strYear3, 10);
if (isNaN(intYear)|| isNaN(intYear1)|| isNaN(intYear2)|| isNaN(intYear3) ) {
err = 4;
return false;
}
if (intMonth>12 || intMonth<1) {
err = 5;
return false;
}
if ((intMonth == 1 || intMonth == 3 || intMonth == 5 || intMonth == 7 || intMonth == 8 || intMonth == 10 || intMonth == 12) && (intday > 31 || intday < 1)) {
err = 6;
return false;
}
if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && (intday > 30 || intday < 1)) {
err = 7;
return false;
}
if (intMonth == 2) {
if (intday < 1) {
err = 8;
return false;
}
if (LeapYear(intYear) == true) {
if (intday > 29) {
err = 9;
return false;
}
}
else {
if (intday > 28) {
err = 10;
return false;
}
}
}

if (strDatestyle == "US") {
datefield.value = strMonth + "/" + strDay + "/" + strYear;
}
else {
datefield.value = strDay + "/" + strMonth + "/" + strYear;
}
return true;
}
function LeapYear(intYear) {
if (intYear % 100 == 0) {
if (intYear % 400 == 0) { return true; }
}
else {
if ((intYear % 4) == 0) { return true; }
}
return false;
}

function doDateCheck(from, to, fromHH ,fromMM, toHH, toMM ) {
if (Date.parse(from.value) < Date.parse(to.value )) {
   return true;
}
else {
if(Date.parse(from.value) == Date.parse(to.value ) )
{
if( ( toHH.value + toMM.value ) >= ( fromHH.value + fromMM.value ) )
return true;
}
if (from.value == "" || to.value == "")
{ 
//alert("Please enter both dates.");
return false;
}
else 
{
//alert("The date and time must occur after the from date and time.");
return false;
}
   }
}




function checkportvalue(objNamevalue) {
if ( objNamevalue.length==0 ||  objNamevalue.charAt(0)=='0' ||  objNamevalue.length>5 || objNamevalue < 1 || isNaN(objNamevalue) ||  objNamevalue > 65535 || objNamevalue.length>5 || objNamevalue.indexOf('.')!=-1) {
return false;
}
else {
return true;
   }
}

// please put onblur="checknumber(this)" in the item you want to check it is a valid number or not. Number range is greater or equal 0.
function checknumber(objName) {
var datefield = objName;
if (  (new RegExp(re_all_whitespace)).test(objName.value) || objName.value.length==0 || objName.value < 0 || isNaN(objName.value) || objName.value.indexOf('.')!=-1  ) {
datefield.select();
//alert("That number is invalid.  Please try again.");
datefield.focus();
return false;
}
else {
objName.value=trimString(objName.value);
return true;
   }
}
// please put onblur="checkip(this)" in the item you want to check it is a valid ip or not. 
function checkip(objName) {
var datefield = objName;
if (objName.value.length!=0 && isValidIPAddress(objName.value) == false && objName.value!="localhost") {
datefield.select();
//alert("That IP is invalid.  Please try again.");
datefield.focus();
return false;
}
else {
return true;
   }
}

function isValidIPAddress(ipaddr) {
   var re = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
   if (re.test(ipaddr)) {
      var parts = ipaddr.split(".");
      if (parseInt(parseFloat(parts[0])) == 0) { return false; }
      for (var i=0; i<parts.length; i++) {
         if (parseInt(parseFloat(parts[i])) > 255) { return false; }
      }
      if (parseInt(parseFloat(parts[parts.length-1])) == 255) { return false; }
      if (parseInt(parseFloat(parts[parts.length-1])) == 0) { return false; }
      return true;
   } else {
      return false;
   }
}
// please put onblur="checkempty(this)" in the item you want to check it is empty or not. It can avoid the item to be empty.
function checkempty(objName) {
var datefield = objName;
if ( objName.value.length==0) {
datefield.select();
//alert("That item cannot be empty or null.  Please try again.");
datefield.focus();
return false;
}
else {
return true;
   }
}

function checkdomain(objName) {
var datefield = objName;
if (objName.value.length!=0 && FSfncValidateDomain(objName) == false) {
datefield.select();
//alert("That domain name is invalid.  Please try again.");
datefield.focus();
return false;
}
else {
return true;
   }
}

function checkipordomain(objName) {
var datefield = objName;
if (FSfncValidateDomain(objName) == false) {
  if(isValidIPAddress(objName.value) == false)
  {	
  	datefield.select();
  	datefield.focus();
       return false;
   }
  else
	return true;
}
else {
	return true;
   }
}

function checkemail(objName) {
var datefield = objName;
if (objName.value.length==0 || FSfncValidateEmailAddress(objName.value) == false) {
datefield.select();
//alert("That email address is invalid.  Please try again.");
datefield.focus();
return false;
}
else {
return true;
   }
}

var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|co|uk)$/;


function FSfncValidateDomainValue(FormFieldValue,NoWWW,CheckTLD) {
	// NoWWW and CheckTLD are optional, both accept values of true, false, and null.
	// NoWWW is used to check that a domain name does not begin with 'www.', eg. for WHOIS lokkups.
    var validChars = '.0123456789';		
	var dots = 0;
     
    for (var i = 0; i < FormFieldValue.length; i++) {
       var chr = FormFieldValue.substring(i,i+1);
       if (chr == '.') {
           dots++;
       }
    }
    
    if (dots > 9)
    return false;

	DomainName=FormFieldValue.toLowerCase();
	
	if (CheckTLD==null) {CheckTLD=true}
	var specialChars="/\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var atom=validChars + '+';
	var atomPat=new RegExp("^" + atom + "$");
        if(DomainName=="localhost")  { return true;}
	var domArr=DomainName.split(".");
	var len=domArr.length;
	if (len==1) { return false;}
	for (i=0;i<len;i++) {if (domArr[i].search(atomPat)==-1) {return false;}}
	if ((CheckTLD) && (domArr[domArr.length-1].length!=2) && (domArr[domArr.length-1].search(knownDomsPat)==-1)) {return false;}
	if ((NoWWW) && (DomainName.substring(0,4).toLowerCase()=="www.")) {return false;}
	return true;
	}

function FSfncValidateDomain(FormField,NoWWW,CheckTLD) {
	// NoWWW and CheckTLD are optional, both accept values of true, false, and null.
	// NoWWW is used to check that a domain name does not begin with 'www.', eg. for WHOIS lokkups.
    var validChars = '.0123456789';		
	var dots = 0;
     
    for (var i = 0; i < FormField.value.length; i++) {
       var chr = FormField.value.substring(i,i+1);
       if (chr == '.') {
           dots++;
       }
    }
    
    if (dots > 9)
    return false;

	DomainName=FormField.value.toLowerCase();
	
	if (CheckTLD==null) {CheckTLD=true}
	var specialChars="/\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var atom=validChars + '+';
	var atomPat=new RegExp("^" + atom + "$");
        if(DomainName=="localhost")  { return true;}
	var domArr=DomainName.split(".");
	var len=domArr.length;
	if (len==1) { return false;}
	for (i=0;i<len;i++) {if (domArr[i].search(atomPat)==-1) {return false;}}
	if ((CheckTLD) && (domArr[domArr.length-1].length!=2) && (domArr[domArr.length-1].search(knownDomsPat)==-1)) {return false;}
	if ((NoWWW) && (DomainName.substring(0,4).toLowerCase()=="www.")) {return false;}
	return true;
	}

function FSfncValidateEmailAddress(FormField,CheckTLD) {
	// CheckTLD is optional, it accepts values of true, false, and null.
	emailStr = FormField.toLowerCase()
	if (CheckTLD==null) {CheckTLD=true}
	var emailPat=/^(.+)@(.+)$/;
	var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var quotedUser="(\"[^\"]*\")";
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom=validChars + '+';
	var word="(" + atom + "|" + quotedUser + ")";
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
	var matchArray=emailStr.match(emailPat);
	if (matchArray==null) {return false;}
	var user=matchArray[1];
	var domain=matchArray[2];
	for (i=0; i<user.length; i++) {if (user.charCodeAt(i)>127) {return false;}}
	for (i=0; i<domain.length; i++) {if (domain.charCodeAt(i)>127) {return false;}}
	if (user.match(userPat)==null) {return false;}
	var IPArray=domain.match(ipDomainPat);
	if (IPArray!=null) {for (var i=1;i<=4;i++) {if (IPArray[i]>255) {return false;}}; return true}
	var atomPat=new RegExp("^" + atom + "$");
        if(domain=="localhost") { return true;}
	var domArr=domain.split(".");
	var len=domArr.length;
	for (i=0;i<len;i++) {if (domArr[i].search(atomPat)==-1) {return false;}}
	if ((CheckTLD) && (domArr[domArr.length-1].length!=2) && (domArr[domArr.length-1].search(knownDomsPat)==-1)) {return false;}
	if (len<2) {return false;}
	return true;
	}

function checkFileName(s)
{
    var i, baseName;
    var re1, re2,re3, result1, result2,result3;
    
    baseName = s.value;
     
    if ( baseName == null || baseName.length == 0 ){
//alert("base is null");
            return false;

    }
//alert("basename: " +baseName);
//alert("File : " + s);
    //make sure base name has no \ / : * ? " < > |
    re1 = new RegExp("[^a-zA-Z0-9_\+\$\.\!\@\#\~\,\%\&\^-]");
    re2 = new RegExp("[^\b]");
	re3 = new RegExp("[*/*]");
    result1 = re1.exec(baseName);
    result2 = re2.exec(baseName);
    result3 = re3.exec(baseName);
	
    if ( result1 != null && result2 != null ){
	           if ( result3 != null ){
			            s.select();
                        //alert("That item cannot contain character "+ result3[0]);
						s.focus();
                        return false;
         }
		 
            if ( result1 != null ){
			            s.select();
					//	if(result1[0]!=" ")
                        //alert("That item cannot contain character " + result1[0]);
					//	else
						//alert("That item cannot contain character space" );
						s.focus();
                        return false;
        }
            if ( result2 != null ){
			            s.select();
                        //alert("That item cannot contain character " + result2[0] );
						s.focus();
                        return false;
        }
    }
    return true;
}

function checkAttachName(s)
{
       for (var i = 0; i < s.value.length; i++) {
       var chr = s.value.substring(i,i+1);
       if ( chr == '\\' || chr == '/'  || chr == '<' || chr == '>' || chr == '|' || chr== '"' )
	   {
        s.select();
        //alert("That item cannot contain character " + chr );
	    s.focus();
        return false; 
       }
    }
	return true;
}



